bitkeeper revision 1.825.1.3 (4062ce06PgXOr3H1PxSNW_qtctjUMg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 25 Mar 2004 12:18:14 +0000 (12:18 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 25 Mar 2004 12:18:14 +0000 (12:18 +0000)
console.c, hypervisor-if.h:
  Fix console for non-DOM0.

xen/include/hypervisor-ifs/hypervisor-if.h
xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c

index 12065a0bcc942535175c7dfc7db90be459006b73..335baee58183d8a2053f94184c910c00b6c3a5a3 100644 (file)
@@ -147,6 +147,9 @@ typedef struct
     unsigned long args[7];
 } multicall_entry_t;
 
+/* Event channel endpoints per domain. */
+#define NR_EVENT_CHANNELS 1024
+
 /*
  * Xen/guestos shared data -- pointer provided in start_info.
  * NB. We expect that this struct is smaller than a page.
index a994f461d807f54f778c6474fe5dfca68372c085..c55cd0146415fc2abd7f5dcb336e4c375437825c 100644 (file)
@@ -32,6 +32,8 @@
 
 static spinlock_t xen_console_lock = SPIN_LOCK_UNLOCKED;
 
+static int console_evtchn;
+
 #define XEN_TTY_MINOR 123
 
 /******************** Kernel console driver ********************************/
@@ -65,7 +67,7 @@ static void nonpriv_conwrite(const char *s, unsigned int count)
         
         ctrl_if->tx_req_prod++;
         evtchn_op.cmd = EVTCHNOP_send;
-        evtchn_op.u.send.local_port = 0;
+        evtchn_op.u.send.local_port = console_evtchn;
         (void)HYPERVISOR_event_channel_op(&evtchn_op);
         
         s     += src;
@@ -118,6 +120,28 @@ static struct console kcons_info = {
 
 void xen_console_init(void)
 {
+    evtchn_op_t op;
+    int i;
+
+    if ( !(start_info.flags & SIF_INITDOMAIN) )
+    {
+        /* Scan the event-channel space to find our control link to DOM0. */
+        for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
+        {
+            op.cmd           = EVTCHNOP_status;
+            op.u.status.dom  = DOMID_SELF;
+            op.u.status.port = i;
+            if ( (HYPERVISOR_event_channel_op(&op) == 0) &&
+                 (op.u.status.status == EVTCHNSTAT_interdomain) &&
+                 (op.u.status.u.interdomain.dom == 0) )
+                break;
+        }
+        
+        /* Bug out if there is no control link. */
+        if ( (console_evtchn = i) == NR_EVENT_CHANNELS )
+            BUG();
+    }
+
     register_console(&kcons_info);
 
     /*
@@ -259,7 +283,7 @@ static void __do_console_io(void)
     {
         /* Send a notification to the controller. */
         evtchn_op.cmd = EVTCHNOP_send;
-        evtchn_op.u.send.local_port = 0;
+        evtchn_op.u.send.local_port = console_evtchn;
         (void)HYPERVISOR_event_channel_op(&evtchn_op);
     }
 }
@@ -467,7 +491,7 @@ int __init xen_con_init(void)
         panic("Couldn't register Xen virtual console driver\n");
 
     if ( !(start_info.flags & SIF_INITDOMAIN) )
-        console_irq = bind_evtchn_to_irq(1);
+        console_irq = bind_evtchn_to_irq(console_evtchn);
     else
         console_irq = bind_virq_to_irq(VIRQ_CONSOLE);
 
@@ -490,7 +514,7 @@ void __exit xen_con_fini(void)
     free_irq(console_irq, NULL);
 
     if ( !(start_info.flags & SIF_INITDOMAIN) )
-        unbind_evtchn_from_irq(1);
+        unbind_evtchn_from_irq(console_evtchn);
     else
         unbind_virq_from_irq(VIRQ_CONSOLE);
 }